# -*- coding: UTF-8 -*- #

from tools.Base import BaseHandler
from tools.BBCode import render_bbcode
from bson import ObjectId
from bson.code import Code
import threading
import time

def cut_post( text ):
        parts = text.split( "<cut>" )
        return parts[0]

def del_cut( text ):
    return text.replace( "<cut>", "" )

_MAPREDUCETIMER = {}

class ThreadMapReduce(threading.Thread):
    def __init__(self,id):
        self.id = id
        threading.Thread.__init__(self)

    def run(self):
        if self.id == 'tags':
            BlogTagsMapReduce().out_res()

class BlogIndex( BaseHandler ):
    def get( self ):
        posts = self.db.blogposts.find().sort('time',-1)
        if posts.count() != 0:
            tags_arr = self.db.tagscount.find().sort('value',-1).limit(10)
        else:
            tags_arr = None
        values = dict( 
            posts = posts,
            tags_arr = tags_arr,
                      )
        self.Render( "blog.index.html", **values )

class BlogNewPost( BaseHandler ):
    def get( self ):
        if not self.is_avt():
            self.redirect( '/avt' )
        values = dict()
        self.Render( "blog.new.html", **values )

    def post( self ):
        if not self.is_avt():
            return self.redirect('/avt')
        title = self.get_argument( "title", "" )
        author = self.user.login
        postcontent = self.get_argument( "postcontent", "" )
        postcontentshort = render_bbcode( cut_post( postcontent ) )
        postcontentbb = render_bbcode( postcontent.replace( "<cut>", "" ) )
        createtime = time.time()
        tags = ( self.get_argument( "tags", "" ) ).split( "," )
        if "" in tags:
            tags.remove("")
        tags_t = []
        for tag in tags:
            if tag not in tags_t:
                tags_t.append(tag.strip())
        self.db.blogposts.insert( 
                                 {'title':title,
                                  'author':author,
                                  'postcontent':postcontent,
                                  'postcontentshort':postcontentshort,
                                  'postcontentbb':postcontentbb,
                                  'time':createtime,
                                  'tags':tags_t,
                                  'comments':[],
                                  } )
        self.do_map_reduce_tags()
        self.redirect( '/blog' )

    def do_map_reduce_tags(self):
        refresh = ThreadMapReduce('tags')
        refresh.start()

class BlogPostView( BaseHandler ):
    def get( self, id ):
        id = ObjectId( str( id ) )
        post = self.db.blogposts.find_one( {'_id':id} )
        values = dict( post = post )
        self.Render( 'blog.postview.html', **values )

class BlogPostEdit( BaseHandler ):
    def get( self, id ):
        mode = self.get_argument( "mode", None )
        id = ObjectId( str( id ) )
        post = self.db.blogposts.find_one( {'_id':id} )
        if post['author'] != self.user.login:
            return self.redirect('/blog')
        if mode == 'delpost':
            self.db.blogposts.remove( {'_id':id} )
            return self.redirect( '/blog' )

        values = dict( post = post )
        self.Render( 'blog.edit.html', **values )

    def post( self, id ):
        id = ObjectId( str( id ) )
        post = self.db.blogposts.find_one( {'_id':id} )
        if post['author'] != self.user.login:
            return self.redirect('/blog')
        title = self.get_argument( "title", None )
        tags = ( self.get_argument( "tags", "" ) ).split( "," )
        if "" in tags:
            tags.remove("")
        tags_t = []
        for tag in tags:
            if tag not in tags_t:
                tags_t.append(tag.strip())
        postcontent = self.get_argument( "postcontent", None )
        postcontentshort = render_bbcode( cut_post( postcontent ) )
        postcontentbb = render_bbcode( postcontent.replace( "<cut>", "" ) )
        self.db.blogposts.update( {'_id':id}, {"$set":
                                              {
                                               'title':title,
                                               'postcontent':postcontent,
                                               'postcontentbb':postcontentbb,
                                               'postcontentshort':postcontentshort,
                                               'tags':tags_t,
                                               }
                                              } )
        self.redirect( "/blog/postview/%s" % id )

class BlogNewPostComment(BaseHandler):
    def post(self, id):
        if not self.is_avt():
            return self.redirect('/avt')
        id = ObjectId( str( id ) )
        post = self.db.blogposts.find_one( {'_id':id} )
        if post:
            commenttext = self.get_argument( "postcomment", "" )
            comment = {
                'author':self.user['login'],
                'time':time.time(),
                'text':render_bbcode(commenttext),
            }
            comments = []
            for comm in post['comments']:
                comments.append(comm)
            comments.append(comment)
            self.db.blogposts.update( {'_id':id}, {"$set":
                                              {
                                               'comments':comments,
                                               }
                                              } )
            return self.redirect('/blog/postview/%s'%id)
        self.redirect('/blog')

class BlogTagsSearch(BaseHandler):
    def get(self):
        tag = self.get_argument( "tag", "" )
        posts = self.db.blogposts.find({'tags':tag}).sort('time',-1)
        if posts.count() == 0:
            posts = None
        self.Render('blog.searchtags.html',**dict(posts=posts, s_tag = tag))

    def post(self):
        tag = self.get_argument( "tag", "" )
        self.redirect("/blog/search/tags?tag=%s"%tag)

class BlogTagsMapReduce(BaseHandler):
    def __init__(self):
        self.map = Code(
"function () {this.tags.forEach(function(z) {emit(z, 1);});}")
        self.reduce = Code(
"function (key, values) {var total = 0;for (var i = 0; i < values.length; i++) {total += values[i];}return total;}")

    def out_res(self):
        self.db.blogposts.map_reduce(self.map, self.reduce, "tagscount")